From 9e7e9110cf9d6383873a825bd805cf8b0740a497 Mon Sep 17 00:00:00 2001 From: "kaf24@labyrinth.cl.cam.ac.uk" Date: Wed, 26 Feb 2003 17:03:13 +0000 Subject: [PATCH] bitkeeper revision 1.104 (3e5cf351zM_u_gdQ7xC6wyGYbvtLAA) e1000_main.c, e1000.h, Makefile: Add some locking to Intel's shoddy e1000 driver. --- xen/drivers/net/Makefile | 1 + xen/drivers/net/e1000/e1000.h | 5 +++-- xen/drivers/net/e1000/e1000_main.c | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/xen/drivers/net/Makefile b/xen/drivers/net/Makefile index 34954de493..22277b13b2 100644 --- a/xen/drivers/net/Makefile +++ b/xen/drivers/net/Makefile @@ -8,6 +8,7 @@ default: $(OBJS) clean: $(MAKE) -C ne clean + $(MAKE) -C e1000 clean rm -f *.o *~ core .PHONY: default clean diff --git a/xen/drivers/net/e1000/e1000.h b/xen/drivers/net/e1000/e1000.h index d94e390ba3..01ee6b98f3 100644 --- a/xen/drivers/net/e1000/e1000.h +++ b/xen/drivers/net/e1000/e1000.h @@ -200,9 +200,10 @@ struct e1000_adapter { struct e1000_phy_info phy_info; struct e1000_phy_stats phy_stats; - - uint32_t pci_state[16]; char ifname[IFNAMSIZ]; + + /* All new definitions should go below this point! */ + spinlock_t tx_lock; }; #endif /* _E1000_H_ */ diff --git a/xen/drivers/net/e1000/e1000_main.c b/xen/drivers/net/e1000/e1000_main.c index 8afbe394c2..dd0de338f0 100644 --- a/xen/drivers/net/e1000/e1000_main.c +++ b/xen/drivers/net/e1000/e1000_main.c @@ -362,6 +362,7 @@ e1000_probe(struct pci_dev *pdev, adapter->netdev = netdev; adapter->pdev = pdev; adapter->hw.back = adapter; + spin_lock_init(&adapter->tx_lock); mmio_start = pci_resource_start(pdev, BAR_0); mmio_len = pci_resource_len(pdev, BAR_0); @@ -1439,6 +1440,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) count++; if(E1000_DESC_UNUSED(&adapter->tx_ring) < count) { + printk("%s: BUG! Ring full with queue awake!\n", netdev->name); netif_stop_queue(netdev); return 1; } @@ -1448,15 +1450,22 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if(adapter->vlgrp && vlan_tx_tag_present(skb)) { tx_flags |= E1000_TX_FLAGS_VLAN; - tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); + tx_flags |= (vlan_tx_tag_get(skb)<tx_lock); + count = e1000_tx_map(adapter, skb); e1000_tx_queue(adapter, count, tx_flags); netdev->trans_start = jiffies; + if(E1000_DESC_UNUSED(&adapter->tx_ring) < (MAX_SKB_FRAGS + 1)) + netif_stop_queue(netdev); + + spin_unlock_irq(&adapter->tx_lock); + return 0; } @@ -1759,6 +1768,9 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) struct pci_dev *pdev = adapter->pdev; struct e1000_tx_desc *tx_desc; int i; + unsigned long flags; + + spin_lock_irqsave(&adapter->tx_lock, flags); i = tx_ring->next_to_clean; tx_desc = E1000_TX_DESC(*tx_ring, i); @@ -1795,6 +1807,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) netif_wake_queue(netdev); } + + spin_unlock_irqrestore(&adapter->tx_lock, flags); } /** -- 2.30.2